home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / statements.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  31KB  |  888 lines

  1. /*  $VER: vbcc (statements.c) V0.4  */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int cont_label=0;
  8. int test_assignment(struct Typ *,np);
  9.  
  10. #define cr()
  11. #ifndef cr
  12. void cr(void)
  13. /*  tested Registerbelegung */
  14. {
  15.     int i;
  16.     for(i=0;i<=MAXR;i++)
  17.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  18. }
  19. #endif
  20. void statement(void)
  21. /*  bearbeitet ein statement                                    */
  22. {
  23.     char *merk;
  24.     cr();
  25.     killsp();
  26.     if(*s=='{'){
  27.         enter_block();
  28.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  29.         compound_statement();leave_block();return;
  30.     }
  31.     merk=s;
  32.     cpbez(buff,0);
  33.     if(!strcmp("if",buff)){if_statement();return;}
  34.     if(!strcmp("switch",buff)){switch_statement();return;}
  35.     if(!strcmp("for",buff)){for_statement();return;}
  36.     if(!strcmp("while",buff)){while_statement();return;}
  37.     if(!strcmp("do",buff)){do_statement();return;}
  38.     if(!strcmp("goto",buff)){goto_statement();return;}
  39.     if(!strcmp("continue",buff)){continue_statement();return;}
  40.     if(!strcmp("break",buff)){break_statement();return;}
  41.     if(!strcmp("return",buff)){return_statement();return;}
  42.     if(!strcmp("case",buff)){labeled_statement();return;}
  43.     killsp();if(*s==':'){labeled_statement();return;}
  44.     /*  fehlt Aufruf der anderen statements */
  45.     s=merk;
  46.     expression_statement();
  47. }
  48. void labeled_statement(void)
  49. /*  bearbeitet labeled_statement                                */
  50. {
  51.     struct llist *lp;int def=0;
  52.     nocode=0;
  53.     if(*s==':'){
  54.         s++;
  55.         if(!*buff){error(130);return;}
  56.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  57.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  58.         if(!lp) lp=add_label(buff);
  59.         lp->flags|=LABELDEFINED;
  60.         lp->switch_count=0;
  61.         if(def){
  62.             if(switch_act==0) error(150);
  63.             lp->flags|=LABELDEFAULT;
  64.             lp->switch_count=switch_act;
  65.         }
  66.         gen_label(lp->label);
  67.         afterlabel=0;
  68.     }else{
  69.         /*  case    */
  70.         np tree;struct llist *lp;
  71.         tree=expression();
  72.         killsp();
  73.         if(*s==':'){s++;killsp();} else error(70);
  74.         if(!switch_count){
  75.             error(132);
  76.         }else{
  77.             if(!tree||!type_expression(tree)){
  78.             }else{
  79.                 if(tree->flags!=CEXPR||tree->sidefx){
  80.                     error(133);
  81.                 }else{
  82.                     if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  83.                         error(134);
  84.                     }else{
  85.                         lp=add_label(empty);
  86.                         lp->flags=LABELDEFINED;
  87.                         lp->switch_count=switch_act;
  88.                         eval_constn(tree);
  89.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  90.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  91.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  92.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  93.                         if(switch_typ==INT) lp->val.vint=vint;
  94.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  95.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  96.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  97.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  98.                         gen_label(lp->label);
  99.                     }
  100.                 }
  101.             }
  102.         }
  103.         if(tree) free_expression(tree);
  104.     }
  105.     cr();
  106.     killsp();
  107.     if(*s!='}') statement();
  108. }
  109. void if_statement(void)
  110. /*  bearbeitet if_statement                                     */
  111. {
  112.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  113.     np tree;struct IC *new;
  114.     killsp(); if(*s=='(') s++; else error(151);
  115.     killsp();cm=nocode;
  116.     tree=expression();
  117.     if(!tree) {error(135);
  118.     }else{
  119.         ltrue=++label;lfalse=++label;
  120.         if(type_expression(tree)){
  121.             tree=makepointer(tree);
  122.             if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER)
  123.                 {error(136);
  124.             }else{
  125.                 if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);
  126.                 gen_IC(tree,ltrue,lfalse);
  127.                 if(tree->flags==CEXPR){
  128.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  129.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0))&&zuleqto(vulong,ul2zul(0UL))) cexpr=2; else cexpr=1;
  130.                 }else cexpr=0;
  131.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  132.                 if(tree->o.flags&&!cexpr){
  133.                     new=mymalloc(ICS);
  134.                     new->code=TEST;
  135.                     new->q1=tree->o;
  136.                     new->q2.flags=new->z.flags=0;
  137.                     new->typf=tree->ntyp->flags;
  138.                     add_IC(new);
  139.                     new=mymalloc(ICS);
  140.                     new->code=BEQ;
  141.                     new->typf=lfalse;
  142.                     add_IC(new);
  143.                 }
  144.                 if(cexpr==2){
  145.                     new=mymalloc(ICS);
  146.                     new->code=BRA;
  147.                     new->typf=lfalse;
  148.                     add_IC(new);
  149.                 }
  150.             }
  151.         }
  152.         free_expression(tree);
  153.     }
  154.     killsp(); if(*s==')') s++; else error(59);
  155.     if(cexpr==2) nocode=1;
  156.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  157.     statement();
  158.     killsp();
  159.     merk=s;
  160.     cpbez(buff,0);
  161.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(cexpr!=1) gen_label(lfalse);return;}
  162.     lout=++label;
  163.     if(cexpr!=2){
  164.         new=mymalloc(ICS);
  165.         new->code=BRA;
  166.         new->typf=lout;
  167.         add_IC(new);
  168.     }
  169.     if(cexpr!=1) {nocode=cm;gen_label(lfalse);}
  170.     if(cexpr==1) nocode=1; else nocode=cm;
  171.     statement();
  172.     nocode=cm;
  173.     if(cexpr!=2) gen_label(lout);
  174.     cr();
  175. }
  176. void switch_statement(void)
  177. /*  bearbeitet switch_statement                                 */
  178. {
  179.     np tree;int merk_typ,merk_count,merk_break;
  180.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  181.     nocode=0;
  182.     killsp();
  183.     if(*s=='('){s++;killsp();} else error(151);
  184.     tree=expression(); killsp();
  185.     if(*s==')'){s++;killsp();} else error(59);
  186.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  187.     if(!tree){
  188.         error(137);
  189.     }else{
  190.         if(!type_expression(tree)){
  191.         }else{
  192.             if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  193.                 error(138);
  194.             }else{
  195.                 int m1,m2,m3,def=0,rm,minflag;
  196.                 zlong l,ml,s;zulong ul,mul,us;
  197.                 if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);
  198.                 m3=break_label=++label;m1=switch_act=++switch_count;
  199.                 m2=switch_typ=tree->ntyp->flags&NU;
  200.                 gen_IC(tree,0,0);
  201.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  202.                     new=mymalloc(ICS);
  203.                     new->code=ASSIGN;
  204.                     new->q1=tree->o;
  205.                     new->q2.flags=0;
  206.                     new->q2.val.vlong=sizetab[m2&NQ];
  207.                     get_scratch(&new->z,m2,0,0);
  208.                     new->typf=m2;
  209.                     tree->o=new->z;
  210.                     add_IC(new);
  211.                 }
  212.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  213.                     int r=tree->o.reg;
  214.                     rm=regs[r];
  215.                     regs[r]=regsa[r];
  216.                 }
  217.                 merk_fic=first_ic;merk_lic=last_ic;
  218.                 first_ic=last_ic=0;
  219.                 statement();
  220.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  221.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  222.                 for(l1=first_llist;l1;l1=l1->next){
  223.                     if(l1->switch_count!=m1) continue;
  224.                     if(l1->flags&LABELDEFAULT){
  225.                         if(def) error(139);
  226.                         def=l1->label;
  227.                         continue;
  228.                     }
  229.                     lp=0;minflag&=~1;
  230.                     for(l2=first_llist;l2;l2=l2->next){
  231.                         if(l2->switch_count!=m1) continue;
  232.                         if(l2->flags&LABELDEFAULT) continue;
  233.                         eval_const(&l2->val,m2);
  234.                         if(minflag&2){
  235.                             if(m2&UNSIGNED){
  236.                                 if(zulleq(vulong,mul)||zuleqto(vulong,mul)) continue;
  237.                             }else{
  238.                                 if(zlleq(vlong,ml)||zleqto(vlong,ml)) continue;
  239.                             }
  240.                         }
  241.                         if(minflag&1){
  242.                             if(m2&UNSIGNED){
  243.                                 if(!(minflag&4)&&zuleqto(vulong,ul)){ error(201);minflag|=4;}
  244.                                 if(zulleq(vulong,ul)){lp=l2;ul=vulong;}
  245.                             }else{
  246.                                 if(!(minflag&4)&&zleqto(vlong,l)){ error(201);minflag|=4;}
  247.                                 if(zlleq(vlong,l)){lp=l2;l=vlong;}
  248.                             }
  249.                         }else{
  250.                             minflag|=1;
  251.                             l=vlong;
  252.                             ul=vulong;
  253.                             lp=l2;
  254.                         }
  255.                     }
  256.                     if(!lp) continue;
  257.                     ml=l;mul=ul;minflag|=2;
  258.                     if(SWITCHSUBS){
  259.                         new=mymalloc(ICS);
  260.                         new->line=0;
  261.                         new->file=0;
  262.                         new->typf=m2;
  263.                         new->code=SUB;
  264.                         new->q1=tree->o;
  265.                         new->z=tree->o;
  266.                         new->q2.flags=KONST;
  267.                         eval_const(&lp->val,m2);
  268.                         vlong=zlsub(vlong,s);
  269.                         vulong=zulsub(vulong,us);
  270.                         vint=zl2zi(vlong);
  271.                         vshort=zl2zs(vlong);
  272.                         vchar=zl2zc(vlong);
  273.                         vuint=zul2zui(vulong);
  274.                         vushort=zul2zus(vulong);
  275.                         vuchar=zul2zuc(vulong);
  276.                         insert_const2(&new->q2.val,m2);
  277.                         new->q1.am=new->q2.am=new->z.am=0;
  278.                         s=l;us=ul;
  279.                         new->prev=merk_lic;
  280.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  281.                         merk_lic=new;
  282.                         new=mymalloc(ICS);
  283.                         new->line=0;
  284.                         new->file=0;
  285.                         new->typf=m2;
  286.                         new->code=TEST;
  287.                         new->q1=tree->o;
  288.                         new->q2.flags=new->z.flags=0;
  289.                         new->prev=merk_lic;
  290.                         new->q1.am=new->q2.am=new->z.am=0;
  291.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  292.                         merk_lic=new;
  293.                     }else{
  294.                         new=mymalloc(ICS);
  295.                         new->line=0;
  296.                         new->file=0;
  297.                         new->code=COMPARE;
  298.                         new->typf=m2;
  299.                         new->q1=tree->o;
  300.                         new->q2.flags=KONST;
  301.                         new->q2.val=lp->val;
  302.                         new->z.flags=0;
  303.                         new->prev=merk_lic;
  304.                         new->q1.am=new->q2.am=new->z.am=0;
  305.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  306.                         merk_lic=new;
  307.                     }
  308.                     new=mymalloc(ICS);
  309.                     new->line=0;
  310.                     new->file=0;
  311.                     new->code=BEQ;
  312.                     new->typf=lp->label;
  313.                     new->q1.flags=new->q2.flags=new->z.flags=0;
  314.                     new->prev=merk_lic;
  315.                     new->q1.am=new->q2.am=new->z.am=0;
  316.                     merk_lic->next=new;
  317.                     merk_lic=new;
  318.                 }
  319.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */
  320.                     new=mymalloc(ICS);
  321.                     new->line=0;
  322.                     new->file=0;
  323.                     new->code=FREEREG;new->typf=0;
  324.                     new->q2.flags=new->z.flags=0;
  325.                     new->q1.flags=REG;
  326.                     new->q1.reg=tree->o.reg;
  327.                     new->prev=merk_lic;
  328.                     new->q1.am=new->q2.am=new->z.am=0;
  329.                     if(merk_lic) merk_lic->next=new; else merk_fic=new;
  330.                     merk_lic=new;
  331.                     regs[tree->o.reg]=regsa[tree->o.reg];
  332.                 }
  333.                 new=mymalloc(ICS);
  334.                 new->line=0;
  335.                 new->file=0;
  336.                 new->code=BRA;
  337.                 if(def) new->typf=def; else new->typf=m3;
  338.                 new->q1.flags=new->q2.flags=new->z.flags=0;
  339.                 if(merk_lic) merk_lic->next=new; else merk_fic=new;
  340.                 new->prev=merk_lic;
  341.                 first_ic->prev=new;
  342.                 new->next=first_ic;
  343.                 new->q1.am=new->q2.am=new->z.am=0;
  344.                 first_ic=merk_fic;
  345.                 gen_label(m3);
  346.             }
  347.         }
  348.     }
  349.     switch_typ=merk_typ;switch_act=merk_count;break_label=merk_break;
  350.     if(tree) free_expression(tree);
  351.     cr();
  352. }
  353. void repair_tree(np p)
  354. /*  Bearbeitet einen Ausdruckbaum so, dass er ein zweites Mal   */
  355. /*  mit gen_IC erzeugt werden kann.                             */
  356. {
  357.     if(p->left) repair_tree(p->left);
  358.     if(p->right) repair_tree(p->right);
  359.     if(p->flags==IDENTIFIER||p->flags==(IDENTIFIER|256))
  360.         p->o.v=find_var(p->identifier,0);
  361.     if(p->flags==CALL){
  362.       struct argument_list *al=p->alist;
  363.       while(al){
  364.     repair_tree(al->arg);
  365.     al=al->next;
  366.       }
  367.     }
  368. }
  369. void while_statement(void)
  370. /*  bearbeitet while_statement                                  */
  371. {
  372.     np tree;int lloop,lin,lout,cm,cexpr,contm,breakm;
  373.     struct IC *new,*mic; int line;char *file;
  374.     killsp();
  375.     if(*s=='(') {s++;killsp();} else error(151);
  376.     tree=expression();
  377.     cexpr=0;
  378.     if(tree){
  379.         if(type_expression(tree)){
  380.             tree=makepointer(tree);
  381.             if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER){
  382.                 error(140);
  383.                 cexpr=-1;
  384.             }else{
  385.                 if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);
  386.                 if(tree->flags==CEXPR){
  387.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  388.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  389.                     if(cexpr==1) error(152);
  390.                 }
  391.             }
  392.         }else cexpr=-1;
  393.     } else error(141);
  394.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  395.     contm=cont_label;breakm=break_label;
  396.     if(!cexpr||tree->sidefx) cont_label=lin; else cont_label=lloop;
  397.     if(!cexpr||tree->sidefx){
  398.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  399.             gen_IC(tree,lloop,lout);
  400.             if(tree->o.flags){
  401.                 new=mymalloc(ICS);
  402.                 new->code=TEST;
  403.                 new->typf=tree->ntyp->flags&NU;
  404.                 new->q1=tree->o;
  405.                 new->q2.flags=new->z.flags=0;
  406.                 add_IC(new);
  407.                 new=mymalloc(ICS);
  408.                 new->code=BEQ;
  409.                 new->typf=lout;
  410.                 add_IC(new);
  411.             }
  412.             repair_tree(tree);
  413.         }else{
  414.             new=mymalloc(ICS);
  415.             new->code=BRA;
  416.             new->typf=lin;
  417.             add_IC(new);
  418.         }
  419.     }
  420.     if(cexpr==1){
  421.         new=mymalloc(ICS);
  422.         new->code=BRA;
  423.         new->typf=lout;
  424.         add_IC(new);
  425.     }else gen_label(lloop);
  426.     line=last_ic->line;file=last_ic->file;
  427.     cm=nocode;break_label=lout;
  428.     if(cexpr==1) nocode=1;
  429.     currentpri*=looppri;
  430.     killsp();
  431.     if(*s==')') {s++;killsp();} else error(59);
  432.     statement();
  433.     mic=last_ic;
  434.     nocode=cm;cont_label=contm;break_label=breakm;
  435.     if(!cexpr||tree->sidefx) gen_label(lin);
  436.     if(tree&&cexpr>=0){
  437.         if(cexpr!=1||tree->sidefx){
  438.             gen_IC(tree,lloop,lout);
  439.             if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  440.         }
  441.         if(tree->o.flags&&!cexpr){
  442.             new=mymalloc(ICS);
  443.             new->code=TEST;
  444.             new->typf=tree->ntyp->flags&NU;
  445.             new->q1=tree->o;
  446.             new->q2.flags=new->z.flags=0;
  447.             add_IC(new);
  448.             new=mymalloc(ICS);
  449.             new->code=BNE;
  450.             new->typf=lloop;
  451.             add_IC(new);
  452.         }
  453.         if(cexpr==2){
  454.             new=mymalloc(ICS);
  455.             new->code=BRA;
  456.             new->typf=lloop;
  457.             add_IC(new);
  458.         }
  459.     }
  460.     if(tree) free_expression(tree);
  461.     for(mic=mic->next;mic;mic=mic->next){
  462.       mic->line=line;mic->file=file;
  463.     }
  464.     gen_label(lout);
  465.     currentpri/=looppri;
  466.     cr();
  467. }
  468. void for_statement(void)
  469. /*  bearbeitet for_statement                                    */
  470. {
  471.     np tree1=0,tree2=0,tree3=0;int lloop,lin,lout,cm,cexpr,contm,breakm;
  472.     struct IC *new,*mic;int line;char *file;
  473.     killsp();
  474.     if(*s=='(') {s++;killsp();} else error(59);
  475.     if(*s!=';') tree1=expression();
  476.     if(tree1){
  477.         if(tree1->flags==POSTINC) tree1->flags=PREINC;
  478.         if(tree1->flags==POSTDEC) tree1->flags=PREDEC;
  479.         if(type_expression(tree1)){
  480.             if(tree1->sidefx){
  481.                 gen_IC(tree1,0,0);
  482.                 if(tree1&&(tree1->o.flags&SCRATCH)) free_reg(tree1->o.reg);
  483.             }else{error(153);}
  484.         }
  485.         free_expression(tree1);
  486.     }
  487.     cexpr=0;
  488.     killsp();
  489.     if(*s==';') {s++;killsp();} else error(54);
  490.     if(*s!=';') {tree2=expression();killsp();} else {cexpr=2;}
  491.     if(*s==';') {s++;killsp();} else error(54);
  492.     if(*s!=')') tree3=expression();
  493.     killsp();
  494.     if(*s==')') {s++;killsp();} else error(59);
  495.     if(tree3){
  496.         if(!type_expression(tree3)){
  497.             free_expression(tree3);
  498.             tree3=0;
  499.         }
  500.     }
  501.     if(tree2){
  502.         if(type_expression(tree2)){
  503.             tree2=makepointer(tree2);
  504.             if(!arith(tree2->ntyp->flags&NQ)&&(tree2->ntyp->flags&NQ)!=POINTER){
  505.                 error(142);
  506.                 cexpr=-1;
  507.             }else{
  508.                 if(tree2->flags==ASSIGN&&tree2->right->flags!=CALL) error(164);
  509.                 if(tree2->flags==CEXPR){
  510.                     eval_const(&tree2->val,tree2->ntyp->flags&NU);
  511.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  512.                     if(cexpr==1) error(152);
  513.                 }
  514.             }
  515.         }else cexpr=-1;
  516.     }
  517.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  518.     contm=cont_label;breakm=break_label;
  519.     cont_label=++label;break_label=lout;
  520.     if(!cexpr||(tree2&&tree2->sidefx)){
  521.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  522.             gen_IC(tree2,lloop,lout);
  523.             if(tree2->o.flags){
  524.                 new=mymalloc(ICS);
  525.                 new->code=TEST;
  526.                 new->typf=tree2->ntyp->flags&NU;
  527.                 new->q1=tree2->o;
  528.                 new->q2.flags=new->z.flags=0;
  529.                 add_IC(new);
  530.                 new=mymalloc(ICS);
  531.                 new->code=BEQ;
  532.                 new->typf=lout;
  533.                 add_IC(new);
  534.             }
  535.             repair_tree(tree2);
  536.         }else{
  537.             new=mymalloc(ICS);
  538.             new->code=BRA;
  539.             new->typf=lin;
  540.             add_IC(new);
  541.         }
  542.     }
  543.     if(cexpr==1){
  544.         new=mymalloc(ICS);
  545.         new->code=BRA;
  546.         new->typf=lout;
  547.         add_IC(new);
  548.     }else gen_label(lloop);
  549.     line=last_ic->line;file=last_ic->file;
  550.     cm=nocode;
  551.     if(cexpr==1) nocode=1;
  552.     currentpri*=looppri;
  553.     statement();
  554.     mic=last_ic;
  555.     nocode=cm;
  556.     gen_label(cont_label);
  557.     cont_label=contm;break_label=breakm;
  558.     if(tree3){
  559.         if(tree3->flags==POSTINC) tree3->flags=PREINC;
  560.         if(tree3->flags==POSTDEC) tree3->flags=PREDEC;
  561.         if(tree3->sidefx){
  562.             gen_IC(tree3,0,0);
  563.             if(tree3&&(tree3->o.flags&SCRATCH)) free_reg(tree3->o.reg);
  564.         }else error(153);
  565.         free_expression(tree3);
  566.     }
  567.     if(!cexpr||(tree2&&tree2->sidefx)) gen_label(lin);
  568.     if(tree2&&cexpr>=0){
  569.         if(cexpr!=1||tree2->sidefx){
  570.             gen_IC(tree2,lloop,lout);
  571.             if((tree2->o.flags&SCRATCH)&&cexpr) free_reg(tree2->o.reg);
  572.         }
  573.         if(tree2->o.flags&&!cexpr){
  574.             new=mymalloc(ICS);
  575.             new->code=TEST;
  576.             new->typf=tree2->ntyp->flags&NU;
  577.             new->q1=tree2->o;
  578.             new->q2.flags=new->z.flags=0;
  579.             add_IC(new);
  580.             new=mymalloc(ICS);
  581.             new->code=BNE;
  582.             new->typf=lloop;
  583.             add_IC(new);
  584.         }
  585.         if(cexpr==2){
  586.             new=mymalloc(ICS);
  587.             new->code=BRA;
  588.             new->typf=lloop;
  589.             add_IC(new);
  590.         }
  591.     }
  592.     if(!tree2&&cexpr==2){
  593.         new=mymalloc(ICS);
  594.         new->code=BRA;
  595.         new->typf=lloop;
  596.         add_IC(new);
  597.     }
  598.     if(tree2) free_expression(tree2);
  599.     for(mic=mic->next;mic;mic=mic->next){
  600.       mic->line=line;mic->file=file;
  601.     }
  602.     gen_label(lout);
  603.     currentpri/=looppri;
  604.     cr();
  605. }
  606. void do_statement(void)
  607. /*  bearbeitet do_statement                                     */
  608. {
  609.     np tree;int lloop,lout,contm,breakm;
  610.     struct IC *new;
  611.     lloop=++label;lout=++label;currentpri*=looppri;
  612.     gen_label(lloop);
  613.     breakm=break_label;contm=cont_label;cont_label=++label;break_label=lout;
  614.     statement();
  615.     killsp();
  616.     gen_label(cont_label);cont_label=contm;break_label=breakm;
  617.     cpbez(buff,0);killsp();
  618.     if(strcmp("while",buff)) error(154);
  619.     if(*s=='(') {s++;killsp();} else error(151);
  620.     tree=expression();
  621.     if(tree){
  622.         if(type_expression(tree)){
  623.             tree=makepointer(tree);
  624.             if(arith(tree->ntyp->flags&NQ)||(tree->ntyp->flags&NQ)==POINTER){
  625.                 if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);
  626.                 if(tree->flags==CEXPR){
  627.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  628.                     if(tree->sidefx) gen_IC(tree,0,0);
  629.                     if(!zdeqto(vdouble,d2zd(0.0))){
  630.                         new=mymalloc(ICS);
  631.                         new->code=BRA;
  632.                         new->typf=lloop;
  633.                         add_IC(new);
  634.                     }
  635.                 }else{
  636.                     gen_IC(tree,lloop,lout);
  637.                     if(tree->o.flags){
  638.                         new=mymalloc(ICS);
  639.                         new->code=TEST;
  640.                         new->typf=tree->ntyp->flags&NU;
  641.                         new->q1=tree->o;
  642.                         new->q2.flags=new->z.flags=0;
  643.                         add_IC(new);
  644.                         new=mymalloc(ICS);
  645.                         new->code=BNE;
  646.                         new->typf=lloop;
  647.                         add_IC(new);
  648.                     }
  649.                 }
  650.             }else error(143);
  651.         }
  652.         free_expression(tree);
  653.     }
  654.     killsp();
  655.     if(*s==')') {s++;killsp();} else error(59);
  656.     if(*s==';') {s++;killsp();} else error(54);
  657.     gen_label(lout);
  658.     currentpri/=looppri;
  659.     cr();
  660. }
  661. void goto_statement(void)
  662. /*  bearbeitet goto_statement                                   */
  663. {
  664.     struct llist *lp;
  665.     struct IC *new;
  666.     killsp();cpbez(buff,1);
  667.     if(!*buff) error(144);
  668.     lp=find_label(buff);
  669.     if(!lp) lp=add_label(buff);
  670.     lp->flags|=LABELUSED;
  671.     new=mymalloc(ICS);
  672.     new->typf=lp->label;
  673.     new->code=BRA;
  674.     new->typf=lp->label;
  675.     add_IC(new);
  676.     killsp();
  677.     if(*s==';'){s++;killsp();} else error(54);
  678.     cr();
  679.     goto_used=1;
  680. }
  681. void continue_statement(void)
  682. /*  bearbeitet continue_statement                               */
  683. {
  684.     struct IC *new;
  685.     if(cont_label==0){error(145);return;}
  686.     new=mymalloc(ICS);
  687.     new->code=BRA;
  688.     new->typf=cont_label;
  689.     add_IC(new);
  690.     killsp();
  691.     if(*s==';') {s++;killsp();} else error(54);
  692.     cr();
  693. }
  694. void break_statement(void)
  695. /*  bearbeitet break_statement                                  */
  696. {
  697.     struct IC *new;
  698.     if(break_label==0){error(146);return;}
  699.     new=mymalloc(ICS);
  700.     new->code=BRA;
  701.     new->typf=break_label;
  702.     add_IC(new);
  703.     killsp();
  704.     if(*s==';') {s++;killsp();} else error(54);
  705.     cr();
  706. }
  707. static void check_auto_return(np tree)
  708. /*  Testet, ob Knoten Adresse einer automatischen Variable ist. */
  709. {
  710.     if((tree->flags==ADDRESS||tree->flags==ADDRESSS||tree->flags==ADDRESSA)&&tree->left->flags==IDENTIFIER){
  711.         struct Var *v;
  712.         if(v=find_var(tree->left->identifier,0)){
  713.             if(v->storage_class==AUTO) error(224);
  714.         }
  715.     }
  716. }
  717. extern int has_return;
  718. void return_statement(void)
  719. /*  bearbeitet return_statement                                 */
  720. /*  SETRETURN hat Groesse in q2.reg und z.reg==freturn(rtyp)    */
  721. {
  722.     np tree;
  723.     struct IC *new;
  724.     has_return=1;
  725.     killsp();
  726.     if(*s!=';'){
  727.         if(tree=expression()){
  728.             if(!return_typ){
  729.                 if(type_expression(tree)){
  730.                     tree=makepointer(tree);
  731.                     if((tree->ntyp->flags&NQ)!=VOID) error(155);
  732.                         else error(225);
  733.                     gen_IC(tree,0,0);
  734.                     if(tree->o.flags&SCRATCH) free_reg(tree->o.reg);
  735.                 }
  736.             }else{
  737.                 if(type_expression(tree)){
  738.                     tree=makepointer(tree);
  739.                     if(tree->flags==ADD||tree->flags==SUB){
  740.                         check_auto_return(tree->left);
  741.                         check_auto_return(tree->right);
  742.                     }else{
  743.                         check_auto_return(tree);
  744.                     }
  745.                     if(!test_assignment(return_typ,tree)){free_expression(tree);return;}
  746.                     gen_IC(tree,0,0);
  747.                     convert(tree,return_typ->flags&NU);
  748. #ifdef OLDPARMS   /*  alte CALL/RETURN-Methode    */
  749.                     new=mymalloc(ICS);
  750.                     new->code=ASSIGN;
  751.                     new->typf=return_typ->flags&NU;
  752.                     new->q1=tree->o;
  753.                     new->q2.flags=0;
  754.                     new->q2.val.vlong=szof(return_typ);
  755.                     if(freturn(return_typ)){
  756.                         new->z.flags=SCRATCH|REG;
  757.                         new->z.reg=freturn(return_typ);
  758.                         if(!regs[new->z.reg]){
  759.                             struct IC *alloc=mymalloc(ICS);
  760.                             alloc->code=ALLOCREG;
  761.                             alloc->q1.flags=REG;
  762.                             alloc->q2.flags=alloc->z.flags=0;
  763.                             alloc->q1.reg=new->z.reg;
  764.                             regs[new->z.reg]=1;
  765.                             add_IC(alloc);
  766.                         }
  767.                     }else{
  768.                         new->z.reg=0;
  769.                         new->z.v=return_var;
  770.                         new->z.flags=SCRATCH|VAR;
  771.                         new->z.val.vlong=l2zl(0L);
  772.                     }
  773.                     add_IC(new);
  774.                     /*  das hier ist nicht sehr schoen, aber wie sonst? */
  775.                     if(new->z.flags&SCRATCH&®s[new->z.reg]) free_reg(new->z.reg);
  776. #else
  777.                     new=mymalloc(ICS);
  778.                     if(return_var){ /*  Returnwert ueber Zeiger */
  779.                         new->code=ASSIGN;
  780.                         new->z.flags=VAR|DREFOBJ;
  781.                         new->z.val.vlong=l2zl(0L);
  782.                         new->z.v=return_var;
  783.                     }else{
  784.                         new->code=SETRETURN;
  785.                         new->z.reg=freturn(return_typ);
  786.                         new->z.flags=0;
  787.                     }
  788.                     new->typf=return_typ->flags&NU;
  789.                     new->q1=tree->o;
  790.                     new->q2.flags=0;
  791.                     new->q2.val.vlong=szof(return_typ);
  792.                     add_IC(new);
  793. #endif
  794.                 }
  795.             }
  796.             free_expression(tree);
  797.             killsp();
  798.             if(*s==';') {s++;killsp();} else error(54);
  799.         }else{
  800.             if(return_typ) error(156);
  801.         }
  802.     }else{ s++; if(return_typ) error(156);}
  803.  
  804.     new=mymalloc(ICS);
  805.     new->code=BRA;
  806.     new->typf=return_label;
  807.     add_IC(new);
  808.     cr();
  809. }
  810.  
  811. void expression_statement(void)
  812. /*  bearbeitet expression_statement                             */
  813. {
  814.     np tree;
  815.     killsp();
  816.     if(*s==';') {s++;return;}
  817.     if(tree=expression()){
  818.         if(tree->flags==POSTINC) tree->flags=PREINC;
  819.         if(tree->flags==POSTDEC) tree->flags=PREDEC;
  820.         if(type_expression(tree)){
  821.             if(DEBUG&2){pre(stdout,tree);printf("\n");}
  822.             if(tree->sidefx){
  823.                 gen_IC(tree,0,0);
  824.                 if((tree->o.flags&(SCRATCH|REG))==REG) ierror(0);
  825.                 if(tree&&(tree->o.flags&SCRATCH)) free_reg(tree->o.reg);
  826.             }else{error(153);if(DEBUG&2) prd(stdout,tree->ntyp);}
  827.         }
  828.         free_expression(tree);
  829.     }
  830.     killsp();
  831.     if(*s==';') s++; else error(54);
  832.     cr();
  833. }
  834. void compound_statement(void)
  835. /*  bearbeitet compound_statement (block)                       */
  836. {
  837.     killsp();
  838.     if(*s=='{') s++; else error(157);
  839.     killsp();
  840.     while(declaration(0)){
  841.         var_declaration();
  842.         killsp();
  843.     }
  844.     while(*s!='}'){
  845.         statement();
  846.         killsp();
  847.     }
  848.     s++;/*killsp();*/
  849. }
  850. struct llist *add_label(char *identifier)
  851. /*  Fuegt label in Liste                                        */
  852. {
  853.     struct llist *new;
  854.     new=mymalloc(LSIZE);
  855.     new->next=0;new->label=++label;new->flags=0;
  856.     new->identifier=add_identifier(identifier,strlen(identifier));
  857.     if(first_llist==0){
  858.         first_llist=last_llist=new;
  859.     }else{
  860.         last_llist->next=new;
  861.         last_llist=new;
  862.     }
  863.     return(last_llist); /* return(new) sollte aequiv. sein */
  864. }
  865. struct llist *find_label(char *identifier)
  866. /*  Sucht Label, gibt Zeiger auf llist oder 0 beu Fehler zurueck    */
  867. {
  868.     struct llist *p;
  869.     p=first_llist;
  870.     while(p){
  871.         if(!strcmp(p->identifier,identifier)) return(p);
  872.         p=p->next;
  873.     }
  874.     return(0);
  875. }
  876. void free_llist(struct llist *p)
  877. /*  Gibt llist frei                                             */
  878. {
  879.     struct llist *merk;
  880.     while(p){
  881.         merk=p->next;
  882.         if(!(p->flags&LABELDEFINED)) error(147,p->identifier);
  883.         if(!(p->flags&LABELUSED)&&!p->switch_count) error(148,p->identifier);
  884.         free(p);
  885.         p=merk;
  886.     }
  887. }
  888.